package pers.cz.javacvdemo.image;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @version 1.0
 * @description:
 * @author: ChengZhi 0336
 * @create: 2025-08-04 17:32
 **/

public class ImageRepair {

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
		//System.loadLibrary("opencv_videoio_ffmpeg470_64");
		//System.loadLibrary("opencv_java470.dll");
	}
	public static void main(String[] args) {
		String filePath = "D:\\temp\\menu.png";

		// 检查文件是否存在
		if (!new java.io.File(filePath).exists()) {
			System.err.println("文件不存在: " + filePath);
			return;
		}

		// 读取图像
		Mat img = Imgcodecs.imread(filePath);
		if (img.empty()) {
			System.err.println("无法读取图像: " + filePath);
			return;
		}

		System.out.println("图像尺寸: " + img.width() + "x" + img.height());
		System.out.println("图像通道数: " + img.channels());

		// 尝试多种方法，选择最佳结果
		System.out.println("正在处理半透明文字水印...");

		// 方法1: 优化后的简单方法
		Mat result1 = removeWatermarkSimple(img);

		// 方法2: 专门针对半透明文字的方法
		Mat result2 = removeSemiTransparentTextWatermark(img);

		// 选择效果更好的结果
		Mat bestResult = (getWatermarkRemovalQuality(img, result1) > getWatermarkRemovalQuality(img, result2)) ? result1 : result2;

		// 显示结果
		displayResults(img, bestResult);

		// 保存结果
		Imgcodecs.imwrite("D:\\temp\\watermark_removed.png", bestResult);
		System.out.println("处理完成，结果已保存");

		// 释放内存
		result1.release();
		result2.release();
		bestResult.release();
		img.release();
	}

	/**
	 * 验证颜色保留情况
	 */
	private static void verifyColorPreservation(Mat original, Mat processed, String methodName) {
		// 计算颜色差异
		Mat diff = new Mat();
		Core.absdiff(original, processed, diff);

		// 计算平均差异
		Scalar meanDiff = Core.mean(diff);
		System.out.println(methodName + " - 颜色差异统计:");
		System.out.println("  蓝色通道平均差异: " + meanDiff.val[0]);
		System.out.println("  绿色通道平均差异: " + meanDiff.val[1]);
		System.out.println("  红色通道平均差异: " + meanDiff.val[2]);

		// 如果差异很小，说明颜色保留良好
		double totalDiff = meanDiff.val[0] + meanDiff.val[1] + meanDiff.val[2];
		if (totalDiff < 10) {
			System.out.println("✓ " + methodName + " - 颜色保留良好");
		} else {
			System.out.println("⚠ " + methodName + " - 颜色可能有轻微变化");
		}

		diff.release();
	}

	/**
	 * 计算颜色差异值
	 */
	private static double getColorDifference(Mat original, Mat processed) {
		Mat diff = new Mat();
		Core.absdiff(original, processed, diff);
		Scalar meanDiff = Core.mean(diff);
		double totalDiff = meanDiff.val[0] + meanDiff.val[1] + meanDiff.val[2];
		diff.release();
		return totalDiff;
	}

	/**
	 * 高级水印去除方法 - 修复版本，确保保留原始颜色
	 */
	public static Mat removeWatermarkAdvanced(Mat img) {
		// 创建结果图像的深拷贝，确保不影响原图
		Mat result = img.clone();

		// 方法1: 基于颜色范围的水印检测
		Mat mask1 = detectWatermarkByColor(img);

		// 方法2: 基于边缘检测的水印检测
		Mat mask2 = detectWatermarkByEdge(img);

		// 方法3: 基于形态学操作的水印检测
		Mat mask3 = detectWatermarkByMorphology(img);

		// 合并所有检测结果
		Mat finalMask = Mat.zeros(img.size(), CvType.CV_8UC1);
		Core.add(mask1, mask2, finalMask);
		Core.add(finalMask, mask3, finalMask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5));
		Imgproc.morphologyEx(finalMask, finalMask, Imgproc.MORPH_CLOSE, kernel);
		Imgproc.morphologyEx(finalMask, finalMask, Imgproc.MORPH_OPEN, kernel);

		// 膨胀操作扩大修复区域
		Imgproc.dilate(finalMask, finalMask, kernel, new Point(-1, -1), 2);

		// 图像修复 - 只修复mask区域，保留其他区域的原色
		Photo.inpaint(result, finalMask, result, 3, Photo.INPAINT_TELEA);

		// 释放所有临时变量
		mask1.release();
		mask2.release();
		mask3.release();
		finalMask.release();

		return result;
	}

	/**
	 * 针对半透明文字水印的优化方法
	 */
	public static Mat removeWatermarkSimple(Mat img) {
		// 创建结果图像的深拷贝，确保不影响原图
		Mat result = img.clone();

		// 方法1: 基于亮度的水印检测
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// 检测高亮度区域（半透明水印通常比背景亮）
		Mat brightMask = new Mat();
		Imgproc.threshold(gray, brightMask, 200, 255, Imgproc.THRESH_BINARY);

		// 方法2: 基于颜色一致性的水印检测
		Mat colorMask = detectSemiTransparentText(img);

		// 合并检测结果
		Mat finalMask = new Mat();
		Core.add(brightMask, colorMask, finalMask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2));
		Imgproc.morphologyEx(finalMask, finalMask, Imgproc.MORPH_CLOSE, kernel);
		Imgproc.morphologyEx(finalMask, finalMask, Imgproc.MORPH_OPEN, kernel);

		// 膨胀操作扩大修复区域
		Imgproc.dilate(finalMask, finalMask, kernel, new Point(-1, -1), 1);

		// 图像修复 - 使用较小的修复半径
		Photo.inpaint(result, finalMask, result, 3, Photo.INPAINT_TELEA);

		// 释放内存
		gray.release();
		brightMask.release();
		colorMask.release();
		finalMask.release();

		return result;
	}

	/**
	 * 检测半透明文字水印
	 */
	private static Mat detectSemiTransparentText(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 转换为LAB颜色空间，更好地检测亮度变化
		Mat lab = new Mat();
		Imgproc.cvtColor(img, lab, Imgproc.COLOR_BGR2Lab);

		// 分离L通道（亮度通道）
		List<Mat> channels = new ArrayList<>();
		Core.split(lab, channels);
		Mat lChannel = channels.get(0);

		// 检测中等亮度区域（半透明水印的特征）
		Mat midMask = new Mat();
		Core.inRange(lChannel, new Scalar(180), new Scalar(240), midMask);

		// 形态学操作连接文字
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 1));
		Imgproc.morphologyEx(midMask, mask, Imgproc.MORPH_CLOSE, kernel);

		// 释放内存
		lab.release();
		lChannel.release();
		midMask.release();

		return mask;
	}

	/**
	 * 专门针对半透明文字水印的去除方法
	 */
	public static Mat removeSemiTransparentTextWatermark(Mat img) {
		Mat result = img.clone();

		// 转换为HSV颜色空间
		Mat hsv = new Mat();
		Imgproc.cvtColor(img, hsv, Imgproc.COLOR_BGR2HSV);

		// 分离HSV通道
		List<Mat> hsvChannels = new ArrayList<>();
		Core.split(hsv, hsvChannels);
		Mat saturation = hsvChannels.get(1);
		Mat value = hsvChannels.get(2);

		// 检测低饱和度、中等亮度的区域（半透明水印特征）
		Mat lowSatMask = new Mat();
		Core.inRange(saturation, new Scalar(0), new Scalar(50), lowSatMask);

		Mat midValueMask = new Mat();
		Core.inRange(value, new Scalar(150), new Scalar(220), midValueMask);

		// 合并条件
		Mat watermarkMask = new Mat();
		Core.bitwise_and(lowSatMask, midValueMask, watermarkMask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2));
		Imgproc.morphologyEx(watermarkMask, watermarkMask, Imgproc.MORPH_CLOSE, kernel);
		Imgproc.morphologyEx(watermarkMask, watermarkMask, Imgproc.MORPH_OPEN, kernel);

		// 膨胀操作扩大修复区域
		Imgproc.dilate(watermarkMask, watermarkMask, kernel, new Point(-1, -1), 1);

		// 图像修复
		Photo.inpaint(result, watermarkMask, result, 3, Photo.INPAINT_TELEA);

		// 释放内存
		hsv.release();
		saturation.release();
		value.release();
		lowSatMask.release();
		midValueMask.release();
		watermarkMask.release();

		return result;
	}

	/**
	 * 评估水印去除质量
	 */
	private static double getWatermarkRemovalQuality(Mat original, Mat processed) {
		// 计算处理后的图像清晰度
		Mat gray = new Mat();
		Imgproc.cvtColor(processed, gray, Imgproc.COLOR_BGR2GRAY);

		// 使用Laplacian算子计算清晰度
		Mat laplacian = new Mat();
		Imgproc.Laplacian(gray, laplacian, CvType.CV_64F);

		Scalar mean = Core.mean(laplacian);
		double clarity = mean.val[0];

		// 释放内存
		gray.release();
		laplacian.release();

		return clarity;
	}

	/**
	 * 基于颜色范围检测水印 - 修复版本，完全保留原始颜色
	 */
	private static Mat detectWatermarkByColor(Mat img) {
		// 创建mask，初始化为全零
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 创建HSV图像的副本，避免影响原图
		Mat hsv = new Mat();
		Imgproc.cvtColor(img, hsv, Imgproc.COLOR_BGR2HSV);

		// 检测白色/浅色水印 (高亮度，低饱和度)
		Mat whiteMask = new Mat();
		Core.inRange(hsv, new Scalar(0, 0, 200), new Scalar(180, 30, 255), whiteMask);

		// 检测半透明水印 (中等亮度，低饱和度)
		Mat semiMask = new Mat();
		Core.inRange(hsv, new Scalar(0, 0, 150), new Scalar(180, 50, 220), semiMask);

		// 合并检测结果到mask中
		Core.add(whiteMask, semiMask, mask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(3, 3));
		Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_CLOSE, kernel);

		// 释放所有临时变量，避免内存泄漏
		hsv.release();
		whiteMask.release();
		semiMask.release();

		return mask;
	}

	/**
	 * 基于边缘检测水印
	 */
	private static Mat detectWatermarkByEdge(Mat img) {
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// 高斯模糊减少噪声
		Imgproc.GaussianBlur(gray, gray, new Size(3, 3), 0);

		// Canny边缘检测
		Mat edges = new Mat();
		Imgproc.Canny(gray, edges, 50, 150);

		// 形态学操作连接边缘
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
		Imgproc.morphologyEx(edges, edges, Imgproc.MORPH_CLOSE, kernel);

		return edges;
	}

	/**
	 * 基于形态学操作检测水印
	 */
	private static Mat detectWatermarkByMorphology(Mat img) {
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// 自适应阈值处理
		Mat thresh = new Mat();
		Imgproc.adaptiveThreshold(gray, thresh, 255,
				Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);

		// 形态学操作
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
		Imgproc.morphologyEx(thresh, thresh, Imgproc.MORPH_OPEN, kernel);
		Imgproc.morphologyEx(thresh, thresh, Imgproc.MORPH_CLOSE, kernel);

		return thresh;
	}

	/**
	 * 显示处理结果
	 */
	private static void displayResults(Mat original, Mat result) {
		int width = original.width();
		int height = original.height();

		// 显示原图
		HighGui.namedWindow("原图", HighGui.WINDOW_AUTOSIZE);
		HighGui.resizeWindow("原图", width / 2, height / 2);
		HighGui.imshow("原图", original);

		// 显示处理后的图
		HighGui.namedWindow("去除水印后", HighGui.WINDOW_AUTOSIZE);
		HighGui.resizeWindow("去除水印后", width / 2, height / 2);
		HighGui.imshow("去除水印后", result);

		HighGui.waitKey(0);
		HighGui.destroyAllWindows();
	}

	/**
	 * 针对特定类型水印的去除方法
	 */
	public static Mat removeSpecificWatermark(Mat img, WatermarkType type) {
		Mat result = img.clone();

		switch (type) {
			case WHITE_TEXT:
				result = removeWhiteTextWatermark(img);
				break;
			case SEMI_TRANSPARENT:
				result = removeSemiTransparentWatermark(img);
				break;
			case LOGO:
				result = removeLogoWatermark(img);
				break;
			case BORDER:
				result = removeBorderWatermark(img);
				break;
		}

		return result;
	}

	/**
	 * 去除白色文字水印
	 */
	private static Mat removeWhiteTextWatermark(Mat img) {
		Mat result = img.clone();

		// 检测白色文字
		Mat hsv = new Mat();
		Imgproc.cvtColor(img, hsv, Imgproc.COLOR_BGR2HSV);

		// 白色范围检测
		Mat whiteMask = new Mat();
		Core.inRange(hsv, new Scalar(0, 0, 220), new Scalar(180, 20, 255), whiteMask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2));
		Imgproc.morphologyEx(whiteMask, whiteMask, Imgproc.MORPH_CLOSE, kernel);

		// 图像修复
		Photo.inpaint(result, whiteMask, result, 3, Photo.INPAINT_TELEA);

		return result;
	}

	/**
	 * 去除半透明水印
	 */
	private static Mat removeSemiTransparentWatermark(Mat img) {
		Mat result = img.clone();

		// 转换为LAB颜色空间
		Mat lab = new Mat();
		Imgproc.cvtColor(img, lab, Imgproc.COLOR_BGR2Lab);

		// 分离通道
		List<Mat> channels = new ArrayList<>();
		Core.split(lab, channels);

		// 对L通道进行阈值处理
		Mat lChannel = channels.get(0);
		Mat thresh = new Mat();
		Imgproc.threshold(lChannel, thresh, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

		// 形态学操作
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5));
		Imgproc.morphologyEx(thresh, thresh, Imgproc.MORPH_CLOSE, kernel);

		// 图像修复
		Photo.inpaint(result, thresh, result, 5, Photo.INPAINT_NS);

		return result;
	}

	/**
	 * 去除Logo水印
	 */
	private static Mat removeLogoWatermark(Mat img) {
		Mat result = img.clone();

		// 边缘检测
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		Mat edges = new Mat();
		Imgproc.Canny(gray, edges, 30, 100);

		// 查找轮廓
		List<MatOfPoint> contours = new ArrayList<>();
		Mat hierarchy = new Mat();
		Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

		// 创建mask
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 筛选合适大小的轮廓
		for (MatOfPoint contour : contours) {
			double area = Imgproc.contourArea(contour);
			if (area > 100 && area < 10000) { // 根据实际情况调整
				Imgproc.fillPoly(mask, Arrays.asList(contour), new Scalar(255));
			}
		}

		// 图像修复
		Photo.inpaint(result, mask, result, 3, Photo.INPAINT_TELEA);

		return result;
	}

	/**
	 * 去除边框水印
	 */
	private static Mat removeBorderWatermark(Mat img) {
		Mat result = img.clone();

		// 检测图像边缘
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// Sobel边缘检测
		Mat sobelX = new Mat();
		Mat sobelY = new Mat();
		Imgproc.Sobel(gray, sobelX, CvType.CV_64F, 1, 0);
		Imgproc.Sobel(gray, sobelY, CvType.CV_64F, 0, 1);

		// 计算梯度幅值
		Mat gradient = new Mat();
		Core.magnitude(sobelX, sobelY, gradient);
		Core.convertScaleAbs(gradient, gradient);

		// 阈值处理
		Mat thresh = new Mat();
		Imgproc.threshold(gradient, thresh, 50, 255, Imgproc.THRESH_BINARY);

		// 形态学操作
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
		Imgproc.morphologyEx(thresh, thresh, Imgproc.MORPH_CLOSE, kernel);

		// 图像修复
		Photo.inpaint(result, thresh, result, 3, Photo.INPAINT_TELEA);

		return result;
	}

	/**
	 * 安全的水印去除方法 - 完全保留原始颜色
	 */
	public static Mat removeWatermarkSafely(Mat img) {
		// 创建结果图像的深拷贝，确保不影响原图
		Mat result = img.clone();

		// 创建水印检测mask
		Mat watermarkMask = createWatermarkMask(img);

		// 使用mask进行图像修复，只修复水印区域
		Photo.inpaint(result, watermarkMask, result, 3, Photo.INPAINT_TELEA);

		// 释放mask内存
		watermarkMask.release();

		return result;
	}

	/**
	 * 创建水印检测mask - 不影响原始图像
	 */
	private static Mat createWatermarkMask(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 方法1: 基于亮度的水印检测
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// 检测高亮度区域（可能是水印）
		Mat brightMask = new Mat();
		Imgproc.threshold(gray, brightMask, 240, 255, Imgproc.THRESH_BINARY);

		// 方法2: 基于颜色一致性的水印检测
		Mat colorMask = detectColorConsistency(img);

		// 合并检测结果
		Core.add(brightMask, colorMask, mask);

		// 形态学操作优化mask
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(3, 3));
		Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_CLOSE, kernel);
		Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_OPEN, kernel);

		// 释放临时变量
		gray.release();
		brightMask.release();
		colorMask.release();

		return mask;
	}

	/**
	 * 基于颜色一致性检测水印
	 */
	private static Mat detectColorConsistency(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 分离BGR通道
		List<Mat> channels = new ArrayList<>();
		Core.split(img, channels);

		Mat blue = channels.get(0);
		Mat green = channels.get(1);
		Mat red = channels.get(2);

		// 计算颜色差异
		Mat diff1 = new Mat();
		Mat diff2 = new Mat();
		Mat diff3 = new Mat();

		Core.absdiff(blue, green, diff1);
		Core.absdiff(green, red, diff2);
		Core.absdiff(blue, red, diff3);

		// 合并差异
		Mat totalDiff = new Mat();
		Core.add(diff1, diff2, totalDiff);
		Core.add(totalDiff, diff3, totalDiff);

		// 检测低颜色差异区域（可能是水印）
		Imgproc.threshold(totalDiff, mask, 30, 255, Imgproc.THRESH_BINARY_INV);

		// 释放内存
		blue.release();
		green.release();
		red.release();
		diff1.release();
		diff2.release();
		diff3.release();
		totalDiff.release();

		return mask;
	}

	/**
	 * 精确水印检测和去除
	 */
	public static Mat removeWatermarkPrecisely(Mat img, WatermarkType type) {
		Mat result = img.clone();

		// 根据水印类型选择检测方法
		Mat watermarkMask = null;
		switch (type) {
			case WHITE_TEXT:
				watermarkMask = detectWhiteTextWatermark(img);
				break;
			case SEMI_TRANSPARENT:
				watermarkMask = detectSemiTransparentWatermark(img);
				break;
			case LOGO:
				watermarkMask = detectLogoWatermark(img);
				break;
			case BORDER:
				watermarkMask = detectBorderWatermark(img);
				break;
			default:
				watermarkMask = detectWatermarkAuto(img);
				break;
		}

		// 优化mask
		watermarkMask = optimizeMask(watermarkMask);

		// 图像修复
		Photo.inpaint(result, watermarkMask, result, 3, Photo.INPAINT_TELEA);

		// 释放内存
		watermarkMask.release();

		return result;
	}

	/**
	 * 自动检测水印类型
	 */
	private static Mat detectWatermarkAuto(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 尝试多种检测方法
		Mat mask1 = detectWhiteTextWatermark(img);
		Mat mask2 = detectSemiTransparentWatermark(img);
		Mat mask3 = detectLogoWatermark(img);

		// 合并检测结果
		Core.add(mask, mask1, mask);
		Core.add(mask, mask2, mask);
		Core.add(mask, mask3, mask);

		// 释放临时变量
		mask1.release();
		mask2.release();
		mask3.release();

		return mask;
	}

	/**
	 * 检测白色文字水印
	 */
	private static Mat detectWhiteTextWatermark(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 转换为灰度图
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		// 检测高亮度区域
		Mat brightMask = new Mat();
		Imgproc.threshold(gray, brightMask, 240, 255, Imgproc.THRESH_BINARY);

		// 形态学操作连接文字
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2));
		Imgproc.morphologyEx(brightMask, mask, Imgproc.MORPH_CLOSE, kernel);

		// 释放内存
		gray.release();
		brightMask.release();

		return mask;
	}

	/**
	 * 检测半透明水印
	 */
	private static Mat detectSemiTransparentWatermark(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 转换为LAB颜色空间
		Mat lab = new Mat();
		Imgproc.cvtColor(img, lab, Imgproc.COLOR_BGR2Lab);

		// 分离L通道
		List<Mat> channels = new ArrayList<>();
		Core.split(lab, channels);
		Mat lChannel = channels.get(0);

		// 检测中等亮度区域
		Mat midMask = new Mat();
		Core.inRange(lChannel, new Scalar(150), new Scalar(220), midMask);

		// 形态学操作
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5));
		Imgproc.morphologyEx(midMask, mask, Imgproc.MORPH_CLOSE, kernel);

		// 释放内存
		lab.release();
		lChannel.release();
		midMask.release();

		return mask;
	}

	/**
	 * 检测Logo水印
	 */
	private static Mat detectLogoWatermark(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 边缘检测
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

		Mat edges = new Mat();
		Imgproc.Canny(gray, edges, 30, 100);

		// 查找轮廓
		List<MatOfPoint> contours = new ArrayList<>();
		Mat hierarchy = new Mat();
		Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

		// 筛选合适大小的轮廓
		for (MatOfPoint contour : contours) {
			double area = Imgproc.contourArea(contour);
			if (area > 200 && area < 5000) { // 根据实际情况调整
				Imgproc.fillPoly(mask, Arrays.asList(contour), new Scalar(255));
			}
		}

		// 释放内存
		gray.release();
		edges.release();
		hierarchy.release();

		return mask;
	}

	/**
	 * 检测边框水印
	 */
	private static Mat detectBorderWatermark(Mat img) {
		Mat mask = Mat.zeros(img.size(), CvType.CV_8UC1);

		// 检测图像边缘区域
		int borderSize = 50; // 边框大小

		// 创建边框mask
		Rect borderRect = new Rect(0, 0, img.width(), img.height());
		Rect innerRect = new Rect(borderSize, borderSize, img.width() - 2 * borderSize, img.height() - 2 * borderSize);

		// 填充边框区域
		Imgproc.rectangle(mask, new Point(0, 0), new Point(img.width(), img.height()), new Scalar(255), -1);
		Imgproc.rectangle(mask, new Point(borderSize, borderSize),
				new Point(img.width() - borderSize, img.height() - borderSize), new Scalar(0), -1);

		return mask;
	}

	/**
	 * 优化mask
	 */
	private static Mat optimizeMask(Mat mask) {
		Mat optimized = mask.clone();

		// 形态学操作
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(3, 3));
		Imgproc.morphologyEx(optimized, optimized, Imgproc.MORPH_CLOSE, kernel);
		Imgproc.morphologyEx(optimized, optimized, Imgproc.MORPH_OPEN, kernel);

		// 膨胀操作扩大修复区域
		Imgproc.dilate(optimized, optimized, kernel, new Point(-1, -1), 1);

		return optimized;
	}

	/**
	 * 水印类型枚举
	 */
	public enum WatermarkType {
		WHITE_TEXT,      // 白色文字水印
		SEMI_TRANSPARENT, // 半透明水印
		LOGO,            // Logo水印
		BORDER           // 边框水印
	}
}

